home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 January / EnigmA AMIGA RUN 33 (1999)(G.R. Edizioni)(IT)[!][issue 1999-01].iso / earcd / apus / latest / bh981121.lha / bh981121 / bootstrap.c < prev    next >
C/C++ Source or Header  |  1980-01-04  |  9KB  |  355 lines

  1. /*
  2. ** linux/arch/m68k/boot/amiga/bootstrap.c -- This program loads the Linux/m68k
  3. **                         kernel into an Amiga and launches
  4. **                         it.
  5. **
  6. ** Copyright 1993,1994 by Hamish Macdonald, Greg Harp
  7. **
  8. ** Modified 11-May-94 by Geert Uytterhoeven
  9. **            (Geert.Uytterhoeven@cs.kuleuven.ac.be)
  10. **     - A3640 MapROM check
  11. ** Modified 31-May-94 by Geert Uytterhoeven
  12. **     - Memory thrash problem solved
  13. ** Modified 07-March-95 by Geert Uytterhoeven
  14. **     - Memory block sizes are rounded to a multiple of 256K instead of 1M
  15. **     This _requires_ >0.9pl5 to work!
  16. **     (unless all block sizes are multiples of 1M :-)
  17. ** Modified 11-July-95 by Andreas Schwab
  18. **     - Support for ELF kernel (untested!)
  19. ** Modified 10-Jan-96 by Geert Uytterhoeven
  20. **     - The real Linux/m68k boot code moved to linuxboot.[ch]
  21. ** Modified 9-Sep-96 by Geert Uytterhoeven
  22. **     - Rewritten option parsing
  23. **     - New parameter passing to linuxboot() (linuxboot_args)
  24. ** Modified 6-Oct-96 by Geert Uytterhoeven
  25. **     - Updated for the new boot information structure
  26. ** Modified 26-Feb-98 by Jesper Skov
  27. **     - Added support for booting APUS systems.
  28. **
  29. ** This file is subject to the terms and conditions of the GNU General Public
  30. ** License.  See the file COPYING in the main directory of this archive
  31. ** for more details.
  32. **
  33. */
  34.  
  35. #include <stddef.h>
  36. #include <stdlib.h>
  37. #include <stdio.h>
  38. #include <stdarg.h>
  39. #include <string.h>
  40. #include <sys/file.h>
  41. #include <sys/types.h>
  42. #include <unistd.h>
  43.  
  44. /* required Linux/m68k include files */
  45. #include <linux/a.out.h>
  46. #include <linux/elf.h>
  47. #include <asm/amigahw.h>
  48. #include <asm/page.h>
  49.  
  50. /* Amiga bootstrap include files */
  51. #include "linuxboot.h"
  52. #include "bootstrap.h"
  53.  
  54.  
  55. /* Library Bases */
  56. long __oslibversion = 36;
  57. extern const struct ExecBase *SysBase;
  58.  
  59. static const char *memfile_name = NULL;
  60.  
  61. static int model = AMI_UNKNOWN;
  62.  
  63. static const char *ProgramName;
  64.  
  65. struct linuxboot_args args;
  66.  
  67.  
  68.     /*
  69.      *  Function Prototypes
  70.      */
  71.  
  72. static void Usage(void) __attribute__ ((noreturn));
  73. int main(int argc, char *argv[]);
  74. static void Puts(const char *str);
  75. static long GetChar(void);
  76. static void PutChar(char c);
  77. static void Printf(const char *fmt, ...);
  78. static int Open(const char *path);
  79. static int Seek(int fd, int offset);
  80. static int Read(int fd, char *buf, int count);
  81. static void Close(int fd);
  82. static int FileSize(const char *path);
  83. static void Sleep(u_long micros);
  84.  
  85.  
  86. static void Usage(void)
  87. {
  88.     fprintf(stderr,
  89.     "Linux/m68k Amiga Bootstrap version " AMIBOOT_VERSION "\n\n"
  90.     "Usage: %s [options] [kernel command line]\n\n"
  91.     "Basic options:\n"
  92.     "    -h, --help           Display this usage information\n"
  93.     "    -k, --kernel file    Use kernel image `file' (default is `vmlinux')\n"
  94.     "    -r, --ramdisk file   Use ramdisk image `file'\n"
  95.     "Advanced options:\n"
  96.     "    -d, --debug          Enable debug mode\n"
  97.     "    -b, --baud speed     Set the serial port speed (default is 9600)\n"
  98.     "    -m, --memfile file   Use memory file `file'\n"
  99.     "    -v, --keep-video     Don't reset the video mode\n"
  100.     "    -t, --model id       Set the Amiga model to `id'\n"
  101.     "    -p, --processor cfm  Set the processor type to `cfm\n",
  102.     "        --apus           PPC boot on PowerUp\n",
  103.     "        --checksum       Make checksum of kernel image.\n\n",
  104.     ProgramName);
  105.     exit(EXIT_FAILURE);
  106. }
  107.  
  108. struct PPCLibBase *PPCLibBasePTR = NULL;
  109.  
  110. int main(int argc, char *argv[])
  111. {
  112.     int i;
  113.     int processor = 0, debugflag = 0, keep_video = 0;
  114.     int apus_boot = 0, checksum = 0;
  115.     u_int baud = 0;
  116.     const char *kernel_name = NULL;
  117.     const char *ramdisk_name = NULL;
  118.     char commandline[CL_SIZE] = "";
  119.  
  120.     ProgramName = argv[0];
  121.     while (--argc) {
  122.     argv++;
  123.     if (!strcmp(argv[0], "-h") || !strcmp(argv[0], "--help"))
  124.         Usage();
  125.     else if (!strcmp(argv[0], "-k") || !strcmp(argv[0], "--kernel"))
  126.         if (--argc && !kernel_name) {
  127.         kernel_name = argv[1];
  128.         argv++;
  129.         } else
  130.         Usage();
  131.     else if (!strcmp(argv[0], "-r") || !strcmp(argv[0], "--ramdisk"))
  132.         if (--argc && !ramdisk_name) {
  133.         ramdisk_name = argv[1];
  134.         argv++;
  135.         } else
  136.         Usage();
  137.     else if (!strcmp(argv[0], "-d") || !strcmp(argv[0], "--debug"))
  138.         debugflag = 1;
  139.     else if (!strcmp(argv[0], "-b") || !strcmp(argv[0], "--baud"))
  140.         if (--argc && !baud) {
  141.         baud = atoi(argv[1]);
  142.         argv++;
  143.         } else
  144.         Usage();
  145.     else if (!strcmp(argv[0], "-m") || !strcmp(argv[0], "--memfile"))
  146.         if (--argc && !memfile_name) {
  147.         memfile_name = argv[1];
  148.         argv++;
  149.         } else
  150.         Usage();
  151.     else if (!strcmp(argv[0], "-v") || !strcmp(argv[0], "--keep-video"))
  152.         keep_video = 1;
  153.     else if (!strcmp(argv[0], "-t") || !strcmp(argv[0], "--model"))
  154.         if (--argc && !model) {
  155.         model = atoi(argv[1]);
  156.         argv++;
  157.         } else
  158.         Usage();
  159.     else if (!strcmp(argv[0], "-p") || !strcmp(argv[0], "--processor"))
  160.         if (--argc && !processor) {
  161.         processor = atoi(argv[1]);
  162.         argv++;
  163.         } else
  164.         Usage();
  165.     else if (!strcmp(argv[0], "--apus"))
  166.         apus_boot = 1;
  167.     else if (!strcmp(argv[0], "--checksum"))
  168.         checksum = 1;
  169.     else
  170.         break;
  171.     }
  172.     if (!kernel_name)
  173.     kernel_name = "vmlinux";
  174.  
  175.     SysBase = *(struct ExecBase **)4;
  176.  
  177.     if (apus_boot) {
  178.       if (!(PPCLibBasePTR = (struct PPCLibBase *) 
  179.           OpenLibrary("ppc.library", 45))){
  180.               fprintf(stderr, "Cannot open ppc.library version45+\n");
  181.               return (FALSE);
  182.           }
  183.     }
  184.  
  185.     /*
  186.      *    Join command line options
  187.      */
  188.     i = 0;
  189.     while (argc--) {
  190.     if ((i+strlen(*argv)+1) < CL_SIZE) {
  191.         i += strlen(*argv) + 1;
  192.         if (commandline[0])
  193.         strcat(commandline, " ");
  194.         strcat(commandline, *argv++);
  195.     }
  196.     }
  197.  
  198.     memset(&args.bi, 0, sizeof(args.bi));
  199.     if (processor) {
  200.     int cpu = processor/100%10;
  201.     int fpu = processor/10%10;
  202.     int mmu = processor%10;
  203.     if (cpu)
  204.         args.bi.cputype = 1<<(cpu-1);
  205.     if (fpu)
  206.         args.bi.fputype = 1<<(fpu-1);
  207.     if (mmu)
  208.         args.bi.mmutype = 1<<(mmu-1);
  209.     }
  210.     /*
  211.      *    If we have a memory file, read the memory information from it
  212.      */
  213.     if (memfile_name) {
  214.     FILE *fp;
  215.     int i;
  216.  
  217.     if ((fp = fopen(memfile_name, "r")) == NULL) {
  218.         perror("open memory file");
  219.         fprintf(stderr, "Cannot open memory file %s\n", memfile_name);
  220.         return(FALSE);
  221.     }
  222.  
  223.     if (fscanf(fp, "%lu", &args.bi.chip_size) != 1) {
  224.         fprintf(stderr, "memory file does not contain chip memory size\n");
  225.         fclose(fp);
  226.         return(FALSE);
  227.     }
  228.  
  229.     for (i = 0; i < NUM_MEMINFO; i++)
  230.         if (fscanf(fp, "%lx %lu", &args.bi.memory[i].addr,
  231.                &args.bi.memory[i].size) != 2)
  232.         break;
  233.  
  234.     fclose(fp);
  235.     args.bi.num_memory = i;
  236.     }
  237.     strncpy(args.bi.command_line, commandline, CL_SIZE);
  238.     args.bi.command_line[CL_SIZE-1] = '\0';
  239.     if (model != AMI_UNKNOWN)
  240.     args.bi.model = model;
  241.  
  242.     args.apus_boot = apus_boot;
  243.     args.checksum = checksum;
  244.  
  245.     args.kernelname = kernel_name;
  246.     args.ramdiskname = ramdisk_name;
  247.     args.debugflag = debugflag;
  248.     args.keep_video = keep_video;
  249.     args.reset_boards = 1;
  250.     args.baud = baud;
  251.     args.puts = Puts;
  252.     args.getchar = GetChar;
  253.     args.putchar = PutChar;
  254.     args.printf = Printf;
  255.     args.open = Open;
  256.     args.seek = Seek;
  257.     args.read = Read;
  258.     args.close = Close;
  259.     args.filesize = FileSize;
  260.     args.sleep = Sleep;
  261.  
  262.     /* Do The Right Stuff */
  263.     linuxboot(&args);
  264.  
  265.     /* if we ever get here, something went wrong */
  266.     exit(EXIT_FAILURE);
  267. }
  268.  
  269.  
  270.     /*
  271.      *  Routines needed by linuxboot
  272.      */
  273.  
  274. static void Puts(const char *str)
  275. {
  276.     fputs(str, stderr);
  277.     fflush(stderr);
  278. }
  279.  
  280. static long GetChar(void)
  281. {
  282.     return(getchar());
  283. }
  284.  
  285. static void PutChar(char c)
  286. {
  287.     fputc(c, stderr);
  288.     fflush(stderr);
  289. }
  290.  
  291. static void Printf(const char *fmt, ...)
  292. {
  293.     va_list args;
  294.  
  295.     va_start(args, fmt);
  296.     vfprintf(stderr, fmt, args);
  297.     va_end(args);
  298.     fflush(stderr);
  299. }
  300.  
  301. static int Open(const char *path)
  302. {
  303.     return(open(path, O_RDONLY));
  304. }
  305.  
  306. static int Seek(int fd, int offset)
  307. {
  308.     return(lseek(fd, offset, SEEK_SET));
  309. }
  310.  
  311.  
  312. static int Read(int fd, char *buf, int count)
  313. {
  314.     return(read(fd, buf, count));
  315. }
  316.  
  317. static void Close(int fd)
  318. {
  319.     close(fd);
  320. }
  321.  
  322. static int FileSize(const char *path)
  323. {
  324.     int fd, size = -1;
  325.  
  326.     if ((fd = open(path, O_RDONLY)) != -1) {
  327.     size = lseek(fd, 0, SEEK_END);
  328.     close(fd);
  329.     }
  330.     return(size);
  331. }
  332.  
  333. static void Sleep(u_long micros)
  334. {
  335.     struct MsgPort *TimerPort;
  336.     struct timerequest *TimerRequest;
  337.  
  338.     if ((TimerPort = CreateMsgPort())) {
  339.     if ((TimerRequest = CreateIORequest(TimerPort,
  340.                         sizeof(struct timerequest)))) {
  341.         if (!OpenDevice("timer.device", UNIT_VBLANK,
  342.                 (struct IORequest *)TimerRequest, 0)) {
  343.         TimerRequest->io_Command = TR_ADDREQUEST;
  344.         TimerRequest->io_Flags = IOF_QUICK;
  345.         TimerRequest->tv_secs = micros/1000000;
  346.         TimerRequest->tv_micro = micros%1000000;
  347.         DoIO((struct IORequest *)TimerRequest);
  348.         CloseDevice((struct IORequest *)TimerRequest);
  349.         }
  350.         DeleteIORequest(TimerRequest);
  351.     }
  352.     DeleteMsgPort(TimerPort);
  353.     }
  354. }
  355.